package com.t3.fx
{
	import com.t3.display.StageObject;
	import com.t3.events.DragEvent;
	import com.t3.util.ArrayUtil;
	
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;

	public class DropArea extends StageObject implements IDropArea
	{
		protected var _droppableObject:Class;
		protected var _objects:Dictionary;
		protected var _bounds:Rectangle;
		protected var _color:Number;
		protected var _alpha:Number;
		
		public function DropArea( bounds:Rectangle, droppableObject:Class, color:Number = 0xCCCCCC, alpha:Number = 1 )
		{
			_alpha = alpha;
			_color = color;
			_bounds = bounds;
			_droppableObject = droppableObject;
			_objects = new Dictionary();
			
			repaint();
			this.stageLoc = new Point( bounds.x, bounds.y );
		}
		
		protected function repaint():void
		{
			this.graphics.beginFill( _color, _alpha );
			this.graphics.drawRect( 0, 0, _bounds.width, _bounds.height );
			this.graphics.endFill();
		}
		
		public function dropObjectAllowed( dob:DraggableObject ):Boolean
		{
			return hitObject.hitTestObject( dob.hitObject ) && dob is _droppableObject;
		}
		
		public function objectDropped( event:DragEvent ):void
		{
			var dob:DraggableObject = event.target as DraggableObject;
			
			if( dob.dragState.dropArea != this )
			{
				objectRemoved( event );
			}
			else if( _objects[ dob.id ] != null )
			{
				_objects[ dob.id ] = dob;
				dob.dragState.dropOrigin = this;
			}
		}
		
		public function objectMoved( event:DragEvent ):void
		{
			var dob:DraggableObject = event.target as DraggableObject;
			
			if( dropObjectAllowed( dob ) )
			{
				dob.dragState.dropArea = this;
				dob.dragState.dropAllowed = true;
			}
			else if( dob.dragState.dropArea == this )
			{
				dob.dragState.dropArea = null;
				dob.dragState.dropAllowed = false;
			}
		}
		
		public function objectRemoved( event:DragEvent ):void
		{
			var dob:DraggableObject = event.target as DraggableObject;
			
			if( _objects[ dob.id ] != null )
			{
				_objects[ dob.id ] = null;
				delete( _objects[ dob.id ] );
			}
		}
		
		public function get hitObject():DisplayObject
		{
			return this;
		}
		
		public function get objects():Dictionary
		{
			return _objects;
		}
		
		public function get objectArr():Array
		{
			return ArrayUtil.dictToArray(_objects);
		}
	}
}